//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <elastos.h>
#include <aura.h>
_ELASTOS_NAMESPACE_USING

typedef void *FILE;

AURA_API FileHelper_Open(Aura_PWChar wszName, FILE *ppFile)
{
    if(NULL == wszName || NULL == ppFile) {
        return AURA_E_INVALID_ARGUMENT;
    }
    
    IDiskManager *pDiskMgr;
    ECode ec = NOERROR;
    
    ec = CSystem::FindRunningObject(L"diskmgr", (IInterface **)&pDiskMgr);
    if(FAILED(ec)) {
        return ec;
    }
    
    WStringBuf_<512> wsbFile;
    IBasicDirectory* pDir = NULL;
    
    ec = pDiskMgr->AcquireDirInterface((const wchar_t*)wszName, &pDir, &wsbFile);
    if (FAILED(ec) || (wsbFile.GetLength() == 0)) {
        
	    pDiskMgr->Release();
	    if (pDir) pDir->Release();
	   	return ec;
	}
	
	pDiskMgr->Release();
    
    IBasicFile *pFile = NULL;
	ec = pDir->Lookup(wsbFile, &pFile);
	pDir->Release();
	if(FAILED(ec)) {
	    if (pFile) pFile->Release();
	    return ec;
	}
	
	IAbsoluteIO *iAb = NULL;
	iAb = IAbsoluteIO::Probe(pFile);

	if (iAb) {
	    iAb->AddRef();
	}
	
	assert(NULL != iAb);

	pFile->Release();
    *ppFile = (FILE)iAb;
    
    return ec;
}


AURA_API FileHelper_GetSize(
        /* [in] */ FILE pFile, 
        /* [out] */ Aura_UInt32 *pSize)
{
    if(NULL == pFile || NULL == pSize) {
        return AURA_E_INVALID_ARGUMENT;
    }
    
    Int32 size; 
    ECode ec = ((IAbsoluteIO *)pFile)->GetSize(&size);
    if(FAILED(ec)) {
//        Aura_printf("IAbsoluteIO::GetSize error, ec = %x. FILE:%s,LINE:%d\n", 
//                ec, __FILE__, __LINE__);
        return ec;
    }
    
    *pSize = size;
    
    return AURA_NOERROR;
}        


AURA_API FileHelper_Read(
        /* [in] */ FILE pFile, 
        /* [in] */ Aura_UInt32 offset, 
        /* [in] */ Aura_UInt32 size,
        /* [out] */ Aura_PVoid *ppBuf)
{
    Aura_Byte*  pBuf = AURA_NULL;
    ECode ec = NOERROR;
    
    if(0 == size || NULL == pFile) {
        return AURA_E_INVALID_ARGUMENT;
    }  
    
    pBuf = (Aura_Byte*)*ppBuf;
    if(NULL == pBuf){
        return AURA_E_OUT_OF_MEMORY;
    }  
    
    MemoryBuf pmd((Aura_Byte*)pBuf, size, 0);
    
    IAbsoluteIO *iAbsoluteIO = NULL;
    iAbsoluteIO = (IAbsoluteIO *)pFile;
    
    ec = iAbsoluteIO->Read(offset, size, &pmd);
    if (ec != NOERROR) {
        return ec;
    }

    return AURA_NOERROR;
}


AURA_API FileHelper_Close(FILE pFile)
{
    ((IAbsoluteIO *)pFile)->Release();
    return AURA_NOERROR;
}

EXTERN_C _ELASTOS Boolean __stdcall DllMain(
    PVoid hDllHandle,
    UInt32 dwReason,
    PVoid preserved)
{
    _ELASTOS Boolean ret = TRUE;
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:
            break;

        case DLL_PROCESS_DETACH:
            break;
    }

    return ret;
}
